package cn.suimg.bilibili.util;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;

public class BiliBiliUtil {

    /**
     * 载入直播间信息地址
     */
    public static final String ROOM_INIT_URL = "https://api.live.bilibili.com/room/v1/Room/room_init";

    /**
     * 获取用户信息地址
     */
    public static final String GET_USER_INFO = "https://api.live.bilibili.com/xlive/web-ucenter/user/get_user_info";

    /**
     * 获取登录令牌地址
     */
    public static final String GET_OAUTH_KEY_URL = "https://passport.bilibili.com/qrcode/getLoginUrl";

    /**
     * 扫码登录地址
     */
    public static final String LOGIN_H5_URL = "http://qr.topscan.com/api.php?text=https://passport.bilibili.com/qrcode/h5/login?oauthKey=%s";

    /**
     * 验证是否扫码登录地址
     */
    public static final String WAIT_FOR_LOGIN_URL = "https://passport.bilibili.com/qrcode/getLoginInfo";

    /**
     * 发送弹幕地址
     */
    public static final String SEND_DANMU_URL = "https://api.live.bilibili.com/msg/send";

    /**
     * 获取用户直播间信息地址
     */
    public static final String GET_USER_ROOM_URL = "https://api.live.bilibili.com/room/v1/Room/getRoomInfoOld?mid=%s";

    /**
     * 对接图灵地址
     */
    public static final String TULING_API_URL = "http://www.tuling123.com/openapi/api?key=5e7035774f6afaf72ae3a7d5a847d979&info=%s";

    /**
     * 登录超时时间(毫秒)
     */
    public static final Long LOGIN_TIME_OUT = 60000L;

    /**
     * Logger
     */
    private static final Logger logger = LoggerFactory.getLogger(BiliBiliUtil.class);

    /**
     * 获取真实的房间ID
     * @param roomId
     * @return
     */
    public static int getRealRoomId(Integer roomId){
        String rawJson = HttpClientUtil.getData(String.format("%s?id=%d", ROOM_INIT_URL, roomId));
        return JSONObject.parseObject(rawJson).getJSONObject("data").getInteger("room_id");
    }

    public static String getUserInfo(Cookie cookie){
        String rawJson = new HttpClientUtil(GET_USER_INFO)
                .setCookie(cookie.toString())
                .exec()
                .getResponseData();
        JSONObject json = JSONObject.parseObject(rawJson);
        JSONObject data = json.getJSONObject("data");
        return String.format("%s(%s)",data.getString("uname"),data.getInteger("uid"));

    }

    /**
     * 获取OauthKey
     * @return
     */
    public static String getOauthKey(){
        String rawJson = HttpClientUtil.getData(GET_OAUTH_KEY_URL);
        return JSONObject.parseObject(rawJson).getJSONObject("data").getString("oauthKey");
    }

    /**
     * 打开浏览器登录窗口
     * @param oauthKey
     */
    public static void openLoginUrl(String oauthKey){
        Runtime runtime = Runtime.getRuntime();
        String osName = System.getProperty("os.name");
        String loginUrl =  String.format(LOGIN_H5_URL,oauthKey);
        logger.info("正在自动打开登录地址。");
        try {
            if(osName.contains("Windows")){
                runtime.exec("cmd /c start" + loginUrl);
            }else if(osName.contains("Mac OS")){
                    runtime.exec("open " + loginUrl);
            }else if(osName.contains("Linux")){
                logger.info("当前系统可能不支持浏览器自动打开，请复制下面链接到浏览器之后再扫描二维码。\n" + loginUrl);
            }
        } catch (IOException e) {
           logger.info("调用系统默认浏览器失败，请复制下面链接到浏览器之后在扫描二维码。\n" +loginUrl);
        }
    }

    /**
     * 等待扫码登录。
     *
     * <pre>
     *      String oauthKey = BiliBiliUtil.getOauthKey();
     *      BiliBiliUtil.openLoginUrl(oauthKey);
     *      Cookie cookie = BiliBiliUtil.waitForLogin(oauthKey);
     * </pre>
     * @param oauthKey
     * @return
     */
    public static Cookie waitForLogin(String oauthKey){

        long startTime = System.currentTimeMillis();

        while (true){
            if(System.currentTimeMillis() - startTime >= LOGIN_TIME_OUT){
                logger.info("登录超时。");
                return null;
            }
            HttpClientUtil clientUtil = new HttpClientUtil().post(WAIT_FOR_LOGIN_URL, new HashMap<String, Object>() {{
                put("oauthKey", oauthKey);
                put("gourl", "https://www.bilibili.com/");
            }}).exec();
            String rawJson = clientUtil.getResponseData();
            JSONObject json = JSONObject.parseObject(rawJson);

            //验证是否登录成功。
            if(!json.getBoolean("status")){
                Integer status = json.getInteger("data");
                switch (status){
                    case -4:
                        logger.info("正在等待扫描");
                        break;
                    case -5:
                        logger.info("正在等待确认");
                }
            }else {
                logger.info("登录成功。");
                return new Cookie(clientUtil.getCookie());
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {}
        }
    }




    /**
     * 发送弹幕接口
     * @param roomId
     * @param content
     * @param cookie
     */
    public static void sendDanmu(int roomId,String content,Cookie cookie){
        new HttpClientUtil().post(SEND_DANMU_URL,new HashMap<String, Object>(){{
            put("color",16777215);
            put("fontsize",25);
            put("mode",1);
            put("msg",content);
            put("rnd",System.currentTimeMillis()/1000);
            put("roomid",roomId);
            put("bubble",0);
            put("csrf_token",cookie.getValue("bili_jct"));
            put("csrf",cookie.getValue("bili_jct"));
        }})
        .setCookie(cookie.toString())
        .exec();
    }

    public static int getUserRoomId(int uid){
        String rawJson = HttpClientUtil.getData(String.format(GET_USER_ROOM_URL, uid));
        JSONObject data = JSONObject.parseObject(rawJson).getJSONObject("data");
        logger.info("直播间标题:{}",data.getString("title"));
        logger.info("直播间ID:{}",data.getInteger("roomid"));
        return data.getInteger("roomid");
    }

    /**
     * 自动回复接口
     * @param info
     * @return
     */
    public static String autoReply(String info) {
        String url = null;
        try {
            url = String.format(TULING_API_URL, URLEncoder.encode(info, "UTF-8"));
        } catch (UnsupportedEncodingException e) { }
        return JSONObject.parseObject(HttpClientUtil.getData(url)).getString("text");
    }

}
